home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 261_01 / pop.c < prev    next >
Text File  |  1988-02-23  |  18KB  |  801 lines

  1. /* pop.c - the operand field parser...
  2.  *    (C) Copyright 1982 Steve Passe
  3.  *    All Rights Reserved
  4.  * 
  5.  * version 1.00
  6.  * created 11/8/82
  7.  * 
  8.  * version 1.01
  9.  *
  10.  *   8/30/83 modified for Aztec ver. 1.05g   smp
  11.  *   12/23/83 modified '*' to evaluate according to rorg smp
  12.  *
  13.  */
  14.  
  15. /* begincode */
  16.  
  17. /* includes */
  18.  
  19. #include <stdio.h>
  20. #include "as68.h"
  21.  
  22. #define    RTERM        0x0100
  23. #define    SLASH        0x0101
  24. #define    HYPHEN        0x0102
  25.  
  26. #define    PC_VALUE    0x0103
  27. #define    IMD        0x0104
  28. #define    COMMA        0x0105
  29. #define    POINT        0x0106
  30. #define    VALUE        0x0107
  31. #define    LVALUE        0x0108
  32. #define    FWRD_REF    0x0109
  33.  
  34. #define    TOP        0x0200
  35. #define    BOTTOM        0x0201
  36. #define    LP        0x0202
  37. #define    RP        0x0203
  38. #define    PLUS        0x0204
  39. #define    MINUS        0x0205
  40. #define    MULT        0x0206
  41. #define    DIV        0x0207
  42. #define    LAND        0x0208
  43. #define    LOR        0x0209
  44. #define    LSHIFT        0x020a
  45. #define    RSHIFT        0x020b
  46. #define    NEGATE        0x020c
  47. #define    LIM_C        1
  48. #define    LM_C        2
  49. #define    RXP        0x0303        /* signals a forced short address */
  50.  
  51. /* externals */
  52.  
  53. extern struct _oprnd op1, op2;      /* structs to hold operand val */
  54. extern struct _symbol *symtbl;
  55. extern char pass;
  56. extern long loc_counter;
  57. extern FLAG abs_long;            /* default to absolute long add.*/
  58. extern FLAG rorg;
  59. extern char statement[STMNT_SIZE];    /* statement line buffer */
  60. extern char *opfld_ptr;
  61. extern long lex_val;
  62. extern char *p;
  63. static FLAG lv = 0;
  64.  
  65. static unsigned reg_num = 0;
  66. static int last_typ = 0;
  67.  
  68. long val_stk[10] = {0L};
  69. int opr_stk[10] = {BOTTOM};
  70. static int val_sp = 0;
  71. static int opr_sp = 0;
  72.  
  73. op_clear(op)
  74. register struct _oprnd *op;
  75. {
  76.     op->_long_val = op->_inxl = op->_rel_lbl = NULL;
  77.     op->_typ = NULL;
  78.     op->_regtyp    = op->_iregtyp = op->_reg = op->_ireg = NULL;
  79. }
  80.  
  81. op_eval(op)
  82. register struct _oprnd *op;
  83. {
  84. /** register int r; */
  85.     register int shorty = NULL;        /* force short address this line */
  86.     long val_push();
  87.  
  88.     last_typ = NULL; 
  89.     opr_sp = val_sp = 0;
  90.     reg_num = NULL;
  91.  
  92. /** this only works if nextfield doesn't eat up all the tabs! **/
  93.     switch (*opfld_ptr)    {
  94.     case '\t':
  95.     case '\n':
  96.     case ' ':
  97.     case NULL:
  98.     return (op->_typ = _none);
  99.     case ',':
  100.     ++opfld_ptr;
  101.     }
  102. top:
  103.     switch (/**r =**/ op_scan(op)) {
  104.     case COMMA:
  105.     case NULL:          /* determine operand type, finalize    values in op */
  106.     reduce(TOP);        /* get into one value */
  107.     switch (op->_typ) {
  108.     case _imd:
  109.         op->_data = val_stk[1];
  110.         return _imd;
  111.     case _reglst:
  112.         return _reglst;
  113.     default:
  114.         if (abs_long) op->_long_val    = TRUE;
  115.         if (shorty)    op->_long_val = FALSE;    /* shorty overrides abs_long
  116.                         AND long values in expression */
  117.         op->_addr = val_stk[1];
  118.         if (!op->_long_val && pass == 2) { /* pass 2/short,    check range */
  119.         if (op->_addr & ~0xffff) {
  120.             op->_addr = 0;
  121.             return (op->_typ = LBL_RANGE);
  122.         }
  123.         }
  124.         return (op->_typ = _address);
  125.     }
  126.     case PLUS:
  127.     reduce(PLUS);
  128.     break;
  129.     case MINUS:
  130.     reduce(MINUS);
  131.     break;
  132.     case MULT:
  133.     reduce(MULT);
  134.     break;
  135.     case DIV:
  136.     reduce(DIV);
  137.     break;
  138.     case LAND:
  139.     reduce(LAND);
  140.     break;
  141.     case LOR:
  142.     reduce(LOR);
  143.     break;
  144.     case LSHIFT:
  145.     reduce(LSHIFT);
  146.     break;
  147.     case RSHIFT:
  148.     reduce(RSHIFT);
  149.     break;
  150.     case NEGATE:
  151.     reduce(NEGATE);
  152.     break;
  153.     case RXP:
  154.     reduce(RP);
  155.     if (val_sp != 1) return (op->_typ = OPRND_EVAL);
  156.     shorty = TRUE;
  157.     break;
  158.     case RP:
  159.     reduce(RP);
  160.     break;
  161.     case LP:
  162.     opr_push(LP);
  163.     break;
  164.     case PC_VALUE:
  165.     if (rorg) op->_rel_lbl = TRUE;
  166.     val_push(loc_counter);
  167.     break;
  168.     case IMD:
  169.     op->_typ = _imd;
  170.     break;
  171.     case LVALUE:
  172.     op->_long_val = TRUE;
  173.     case VALUE:
  174.     val_push(lex_val);
  175.     break;
  176.     case FWRD_REF:
  177. /** op->_forward = TRUE; ? */
  178.     val_push(lex_val);
  179.     break;
  180.     case _an:
  181.     return (op->_typ = _an);
  182.     case _dn:
  183.     return (op->_typ = _dn);
  184.     case _pd_ani:
  185.     return (op->_typ = _pd_ani);
  186.     case _ani_pi:
  187.     return (op->_typ = _ani_pi);
  188.     case _ani:
  189.     if (val_sp == 0) {
  190.         return (op->_typ = _ani);
  191.     }
  192.     if (reduce(TOP)    != 1) return (op->_typ = OPRND_EVAL);
  193.     op->_displ = val_stk[1];
  194.     return (op->_typ = _d16_ani);
  195.     case _pc:
  196.     if (reduce(TOP)    != 1) return (op->_typ = OPRND_EVAL);
  197.     op->_displ = val_stk[1];
  198.     return (op->_typ = (op->_iregtyp ? _labeli : _label));
  199. /**    return (op->_typ = _labeli); **/
  200.     case _an_inx:
  201.     if (reduce(TOP)    != 1) return (op->_typ = OPRND_EVAL);
  202.     op->_displ = val_stk[1];
  203.     return (op->_typ = _d8_anx);
  204.     case _ccr:      return (op->_typ = _ccr);
  205.     case _sr:       return (op->_typ = _sr);
  206.     case _usp:      return (op->_typ = _usp);
  207.     case _reglst:   return (op->_typ = _reglst);
  208.  
  209.     case ERROR:
  210.     default:
  211.     return (op->_typ = OPRND_EVAL);
  212.     }
  213.     goto top;
  214. }
  215.  
  216. reduce(tkn)
  217. int tkn;
  218. {
  219.     long val_push(), val_pop();
  220.     long temp;
  221.  
  222.     while (opr_stk[opr_sp] >= (tkn & ~1)) {
  223.     switch (opr_stk[opr_sp--]) {
  224.     case PLUS:
  225.         val_push(val_pop() + val_pop());
  226.         continue;
  227.     case MINUS:
  228.         temp = val_pop();
  229.         val_push(val_pop() - temp);
  230.         continue;
  231.     case MULT:
  232.         val_push(val_pop() * val_pop());
  233.         continue;
  234.     case DIV:
  235.         temp = val_pop();
  236.         val_push(val_pop() / temp);
  237.         continue;
  238.     case LAND:
  239.         val_push(val_pop() & val_pop());
  240.         continue;
  241.     case LOR:
  242.         val_push(val_pop() | val_pop());
  243.         continue;
  244.     case LSHIFT:
  245.         temp = val_pop();
  246.         val_push(val_pop() << temp);
  247.         continue;
  248.     case RSHIFT:
  249.         temp = val_pop();
  250.         val_push(val_pop() >> temp);
  251.         continue;
  252.     case NEGATE:
  253.         val_push(-1    * val_pop());
  254.         continue;
  255.     case LP :
  256.         return val_sp;
  257.     case BOTTOM:
  258.         ++opr_sp;
  259.         return val_sp;
  260.     }
  261.     }
  262.     opr_push(tkn);
  263.     return val_sp;
  264. }
  265.  
  266. long
  267. val_push(l)
  268. long l;
  269. {
  270.     return (val_stk[++val_sp] = l);
  271. }
  272.  
  273. long
  274. val_pop()
  275. {
  276.     return (val_stk[val_sp--]);
  277. }
  278.  
  279. opr_push(t)
  280. int t;
  281. {
  282.     return (opr_stk[++opr_sp] = t);
  283. }
  284.  
  285. opr_pop()
  286. {
  287.     return (opr_stk[opr_sp--]);
  288. }
  289.  
  290. op_scan(op)
  291. register struct _oprnd *op;
  292. {
  293.     register int typ, len;
  294.     char s[32];
  295.     long _dtol(), _htol(), _btol(), _actol();
  296.  
  297.     p = opfld_ptr;
  298.  
  299.     if (typ = reg_scan(op)) {
  300.     opfld_ptr = p;
  301.     if (typ > 0) return typ;
  302.     goto foops;
  303.     }
  304.     switch (*opfld_ptr++) {
  305.     case '-':   /* choose between NEGATE and MINUS */
  306.     switch (last_typ) {
  307.     case NULL:
  308.     case IMD:
  309.     case LP:
  310.     case PLUS:
  311.     case MINUS:
  312.     case MULT:
  313.     case DIV:
  314.     case LAND:
  315.     case LOR:
  316.         return (last_typ = NEGATE);
  317.     case RXP:
  318.     case LSHIFT:
  319.     case RSHIFT:
  320.         goto foops;
  321.     default:
  322.         return (last_typ = MINUS);
  323.     }
  324.     case '(':                       /* (        */
  325.     return (last_typ = LP);
  326.     case ')':                       /* )        */
  327.     if (opfld_ptr[0] == '.'             /* ).s        */
  328.         && (opfld_ptr[1] == 's' || opfld_ptr[1] == 'S')) {
  329.         p = (opfld_ptr += 2);    /* skip the '.s' */
  330.         return (last_typ = RXP);
  331.     }
  332.     else return (last_typ = RP);
  333.     case '#':                       /* #        */
  334.     return (last_typ = IMD);
  335.     case '$':                       /* $        */
  336.     lex_val    = _htol();
  337.     return (last_typ = (lv) ? LVALUE : VALUE);
  338.     case '%':                       /* %        */
  339.     lex_val    = _btol();
  340.     return (last_typ = VALUE);
  341.     case '*':                       /* *        */
  342.     switch (last_typ) {
  343.     case NULL:
  344.     case IMD:
  345.     case LP:
  346.     case PLUS:
  347.     case MINUS:
  348.     case MULT:
  349.     case DIV:
  350.     case LAND:
  351.     case LOR:
  352.     case LSHIFT:
  353.     case RSHIFT:
  354.         return (last_typ = PC_VALUE);
  355.     case RXP: goto foops;
  356.     default:
  357.         return (last_typ = MULT);
  358.     }
  359.     case '/':                       /* /        */
  360.     return (last_typ = DIV);
  361.     case '+':                       /* +        */
  362.     return (last_typ = PLUS);
  363.     case '&':                       /* &        */
  364.     return (last_typ = LAND);
  365.     case '!':                       /* !        */
  366.     return (last_typ = LOR);
  367.     case '>':                       /* >...        */
  368.     if (*opfld_ptr++ != '>') goto foops;        /* >FAIL        */
  369.     return (last_typ = RSHIFT);            /* >>        */
  370.     case '<':                       /* <...        */
  371.     if (*opfld_ptr++ != '<') goto foops;        /* <FAIL        */
  372.     return (last_typ = LSHIFT);            /* <<        */
  373.     case '\'':                      /* '        */
  374.     lex_val    = _actol();